#include <iostream>
using namespace std;
#include <unistd.h>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include "log.hpp"
#include <netinet/in.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <functional>
#include <signal.h>
#include <pthread.h>

namespace Server
{
    typedef function<void*(void*)> func_t;


    class tcpServer
    {
    public:
        tcpServer(const func_t &func, const uint16_t &port = 8080) : _callback(func), _port(port), listen_sock(-1)
        {
        }
        void initServer()
        {
            listen_sock = socket(AF_INET, SOCK_STREAM, 0);
            if (listen_sock < 0)
            {
                logMessage(4, "socket errno");
                exit(1);
            }
            logMessage(1, "socket success");

            // 链接
            struct sockaddr_in local;
            memset(&local, 0, sizeof(local));
            local.sin_family = AF_INET;
            local.sin_port = htons(_port);
            local.sin_addr.s_addr = INADDR_ANY; // 任意地址ip

            int n = bind(listen_sock, (sockaddr *)&local, sizeof(local));
            if (n < 0)
            {
                logMessage(4, "bind errno");
                exit(1);
            }
            logMessage(1, "bind success");

            // 设置为监听
            int ret = listen(listen_sock, 5);
            if (ret < 0)
            {
                logMessage(4, "listen errno");
            }
            logMessage(1, "listen success");
        }

        void start()
        {
            signal(17, SIG_IGN); // 通过信号忽略的方式，这样就不用进行进程等待了

            // 服务器接受数据并且处理后返回给客户端
            while (1)
            {
                struct sockaddr_in peer;
                socklen_t len = sizeof(peer);
                int sock = accept(listen_sock, (sockaddr *)&peer, &len);
                if (sock < 0)
                {
                    logMessage(3, "accept errno");
                    continue;
                }
                logMessage(1, "accept success");

                cout << "sock :" << sock << endl;
                // 后面的io流操作都是用这个文件描述符来操作了

                // 2:多进程版本
                // pid_t id = fork();
                // if (id == 0)
                // {
                //         _callback(sock);
                //         close(listen_sock);
                // }
                // else
                // {
                //     // 父进程的fd不用使用通信
                //     close(sock);
                // }

                // 3：多线程的版本
                while (1)
                {
                    pthread_t t1;
                    //pthread_create(&t1, nullptr, _callback, (void*)sock);
                }
            }
        }


        ~tcpServer()
        {
        }

    private:
        int listen_sock;
        uint16_t _port;

        func_t _callback;
    };
}